from django.shortcuts import render, get_object_or_404
from django.core.urlresolvers import reverse
from django.http import JsonResponse, HttpResponseRedirect, Http404
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, authenticate, password_validation, logout
from django.core.exceptions import ValidationError

from content.models import PostModel
from user.forms import LoginForm, RegisterForm, SettingForm, RepassForm, CommentForm
from user.models import BBSUser, CommentModel, MessageModel
from bbs.utils import set_verify_num, get_verify_num, get_pages_data


# Create your views here.
def login_view(request):
    ver_code = ''
    next_page = request.GET.get('next', reverse('index'))

    if request.method != 'POST':
        ver_code = set_verify_num(request)
        form = LoginForm()
    else:
        form = LoginForm(request.POST)
        if form.is_valid():
            user = authenticate(
                email=request.POST['email'],
                password=request.POST['password']
            )
            if not user:
                status = 1
                msg = "用户名或密码错误"
            else:
                login(request, user)
                status = 0
                msg = "登录成功"

            if get_verify_num(request) != int(form.cleaned_data['ver_code']):
                status = 2
                msg = "验证码错误"
        else:
            status = 3
            msg = "信息填写格式有误，请重新检查"

        return JsonResponse({
            "status": status,
            "msg": msg,
            "action": next_page
        })

    if request.user.is_authenticated:
        return HttpResponseRedirect(next_page)
    return render(request, "user/login.html", {
        'form': form,
        'ver_code': ver_code,
        'title': '登录'
    })


def logout_view(request):
    """注销用户"""
    logout(request)
    # 支持可选的登出重定向地址
    next_path = request.GET.get('next')
    return HttpResponseRedirect(next_path) if next_path else HttpResponseRedirect('/')


def register(request):
    if request.method != 'POST':
        if request.user.is_authenticated:
            return HttpResponseRedirect(reverse('index'))
        ver_code = set_verify_num(request)
        return render(request, "user/register.html", {'ver_code': ver_code, 'title': '注册'})

    ret_dict = {'action': reverse('index')}
    form = RegisterForm(request.POST)
    if form.is_valid():
        nickname = form.cleaned_data.get('username')
        password = form.cleaned_data.get('re_password')
        if form.cleaned_data.get('password') != password:
            ret_dict['status'] = 4
            ret_dict['msg'] = "两次输入的密码不一致，请重新输入"
            return JsonResponse(ret_dict)
        # 检验密码合法性
        password_validators = password_validation.get_default_password_validators()
        for validator in password_validators:
            try:
                validator.validate(password)
            except ValidationError as error:
                ret_dict['status'] = 5
                ret_dict['msg'] = error.messages[0]
                return JsonResponse(ret_dict)
        # 检查验证码
        if get_verify_num(request) != int(form.cleaned_data['ver_code']):
            ret_dict['status'] = 2
            ret_dict['msg'] = "验证码错误"
            return JsonResponse(ret_dict)

        # 检查重复用户
        if BBSUser.objects.filter(email=form.cleaned_data.get('email')):
            ret_dict['status'] = 6
            ret_dict['msg'] = "已存在相同邮箱的用户"
            return JsonResponse(ret_dict)

        user = BBSUser.objects.create_user(form.cleaned_data.get('email'), password, nickname=nickname)
        # TODO:发送注册邮箱，用户点击邮箱内的链接后才真正注册
        login(request, user)
        ret_dict['status'] = 0
        ret_dict['msg'] = "注册成功，正在跳转到首页"
    else:
        ret_dict['status'] = 3
        ret_dict['msg'] = "信息填写格式有误，请重新检查"
    return JsonResponse(ret_dict)


def home(request, user_id=None):
    context = {'title': '个人主页'}
    if user_id:
        context['user_info'] = get_object_or_404(BBSUser, pk=user_id)
    elif request.user.is_authenticated:
        user = request.user
    else:
        raise Http404

    posts = PostModel.objects.filter(creator=user)
    comments = CommentModel.objects.filter(user=user)
    context.update({'posts': posts, 'comments': comments})
    return render(request, "user/home.html", context)


@login_required
def setting(request):
    if request.method == 'GET':
        return render(request, "user/setting.html", {'page_name': 'user', 'title': '个人设置'})

    form = SettingForm(request.POST)
    if not form.is_valid():
        return JsonResponse({'status': 3, 'msg': '信息填写有误，请重新检查'})

    # 读取数据
    username = form.cleaned_data['username']
    sex = form.cleaned_data.get('sex', 'male')
    city = form.cleaned_data.get('city', '')
    desc = form.cleaned_data.get('desc', '')
    user_info = request.user
    user_info.sex = sex
    user_info.city = city
    user_info.desc = desc
    user_info.save()
    return JsonResponse({'status': 0, 'msg': '修改成功'})


@login_required
def repass(request):
    if request.method == 'GET':
        return render(request, "user/setting.html", {'page_name': 'user', 'title': '个人设置'})

    form = RepassForm(request.POST)
    if not form.is_valid():
        return JsonResponse({'status': 3, 'msg': '信息填写有误，请重新检查'})

    password = form.cleaned_data['repassword']
    if not request.user.check_password(form.cleaned_data['nowpassword']):
        return JsonResponse({'status': 8, 'msg': '当前密码错误'})
    if form.cleaned_data['password'] != password:
        return JsonResponse({'status': 9, 'msg': '两次输入的密码不一致'})

    # 检验密码合法性
    password_validators = password_validation.get_default_password_validators()
    for validator in password_validators:
        try:
            validator.validate(password)
        except ValidationError as error:
            return JsonResponse({'status': 5, 'msg': error.messages[0]})

    request.user.set_password(password)
    request.user.save()
    return JsonResponse({'status': 0, 'msg': '修改成功'})


def find_user(request):
    user = get_object_or_404(BBSUser, nickname=request.GET.get('username', ''))
    return HttpResponseRedirect(reverse("user_home_other", args=(user.pk,)))


@login_required
def user_posts(request):
    posts = PostModel.objects.filter(creator=request.user).order_by('-create_at')
    favs = PostModel.objects.filter(like=request.user)
    return render(request, "user/posts.html", {
        'posts': posts,
        'favs': favs,
        'title': '我的帖子'
    })


@login_required
def messages(request):
    user = request.user
    messages = MessageModel.objects.filter(target=user)

    try:
        page = int(request.GET.get('page', 1))
    except ValueError:
        page = 1
    messages, page_range = get_pages_data(messages, 10, page)
    return render(request, "user/message.html", {
        'title': '我的消息',
        'messages': messages,
        'page_range': page_range
    })


@login_required
def add_comment(request):
    post = get_object_or_404(PostModel, pk=int(request.POST.get('id')))
    form = CommentForm(data=request.POST)
    if form.is_valid():
        comment = form.save(commit=False)
        comment.post = post
        comment.user = request.user
        comment.save()
        return JsonResponse({'status': 0, 'msg': '回帖成功'})
    else:
        return JsonResponse({'status': 1, 'msg': '填写数据错误'})


@login_required
def comment_action(request, comment_id):
    action = request.POST.get('action')
    status = request.POST.get('status')
    if not action or not status:
        return JsonResponse({'status': 1, 'msg': '参数错误'}, status=400)
    try:
        status = bool(int(status))
    except ValueError:
        return JsonResponse({'status': 1, 'msg': '参数错误'}, status=400)

    comment = get_object_or_404(CommentModel, pk=comment_id)
    user = request.user
    if action == 'like':
        if status:
            comment.likers.add(user)
        else:
            comment.likers.remove(user)
    elif action == 'adopt':
        comment.is_adopted = status
        comment.post.accepted = status
        comment.user.coin += comment.post.reward

        comment.user.save()
        comment.post.save()
    elif action == 'edit':
        if not status:
            return JsonResponse({"status": 0, "data": comment.content})
        else:
            comment.content = request.POST.get('content', '')
    elif action == 'delete':
        comment.delete()
        if comment.is_adopted:
            comment.post.accepted = False
            comment.user.coin -= comment.post.reward

            comment.user.save()
            comment.post.save()
        return JsonResponse({'status': 0, 'msg': '删除成功'})
    else:
        return JsonResponse({'status': 1, 'msg': '参数错误'}, status=400)

    comment.save()
    return JsonResponse({'status': 0, 'msg': '操作成功'})
